package org.ala.tiktools.mybatis.expand.executor;

import ch.qos.logback.core.net.ssl.SSL;
import org.ala.tiktools.logs.LoggerFactory;
import org.apache.ibatis.executor.SimpleExecutor;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.jdbc.ConnectionLogger;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.transaction.Transaction;
import org.slf4j.Logger;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

/**
 * @author ala
 * @date 2025-03-25 11:05
 */
public class SimpleExecutorExpander extends SimpleExecutor {

    static Logger log = LoggerFactory.getLogger("shard", "executor");

    public SimpleExecutorExpander(Configuration configuration, Transaction transaction) {
        super(configuration, transaction);
    }


    @Override
    public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
        Statement stmt = null;
        long now = System.currentTimeMillis();
        try {
            Configuration configuration = ms.getConfiguration();
            StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
            stmt = prepareStatement(handler, ms.getStatementLog());
            long t1 = System.currentTimeMillis() - now;
            now = System.currentTimeMillis();

            List<E> res = handler.<E>query(stmt, resultHandler);
            long t2 = System.currentTimeMillis() - now;

//            log.info(String.format("thread:%s 拿链接耗时：%d 执行耗时：%d\n ", Thread.currentThread().getName(), t1, t2));
            return res;
        } finally {
            closeStatement(stmt);
        }
    }
    private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
        Statement stmt;
        Connection connection = getConnection(statementLog);
        stmt = handler.prepare(connection, transaction.getTimeout());
        handler.parameterize(stmt);
        return stmt;
    }
    protected Connection getConnection(Log statementLog) throws SQLException {
        Connection connection = transaction.getConnection();
        if (statementLog.isDebugEnabled()) {
            return ConnectionLogger.newInstance(connection, statementLog, queryStack);
        } else {
            return connection;
        }
    }
}
